package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_UP_KEY;

@Service
@Slf4j
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private CategoryMapper categoryMapper;

    public PageResult<SpuDTO> findSpuByPage(Integer page, Integer rows, String key, Boolean saleable) {

//        构建条件
//        Spu spu = new Spu(); //此方式不支持模糊查询
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
//        关键字查询  查询名称字段
        if(StringUtils.isNotBlank(key)){
            criteria.andLike("name","%"+key+"%");
        }
//        是否上下架
        if(saleable!=null){
            criteria.andEqualTo("saleable",saleable);
        }
//        按照更新时间倒序
        example.setOrderByClause("update_time desc");  //排序字段的写法是列名 不是字段名
        PageHelper.startPage(page,rows);
        List<Spu> spuList = spuMapper.selectByExample(example);
        PageInfo pageInfo = new PageInfo(spuList);

//        把spu转成spuDTO
        List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(spuList, SpuDTO.class);
//        把brandId和categoryIds转成名称
        spuDTOList.forEach(spuDTO -> {
//            根据brandId查询brand对象
            Long brandId = spuDTO.getBrandId();
            Brand brand = brandMapper.selectByPrimaryKey(brandId);
            spuDTO.setBrandName(brand.getName());

            List<Long> categoryIds = spuDTO.getCategoryIds(); //三个分类id
//             根据id的集合查询
            List<Category> categoryList = categoryMapper.selectByIdList(categoryIds);
//            取categoryList集合中每个对象的名称并且把名称用“/”分隔
            String categoryNames = categoryList.stream().map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(categoryNames);
        });

        return new PageResult<SpuDTO>(pageInfo.getTotal(),spuDTOList);

    }

    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;

    @Transactional
    public void saveGoods(SpuDTO spuDTO) {
//        涉及到三张表
//        tb_spu  spuDTO
//        把spuDTO转成spu对象
        try {
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            spuMapper.insertSelective(spu);  //id  saleable  createTime  updateTime

//         tb_spu_detail spuDTO.getSpuDetail
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
            spuDetail.setSpuId(spu.getId());  //设置一对一的关系
            spuDetailMapper.insertSelective(spuDetail);
//        tb_sku  spuDTO.getSkus
            List<SkuDTO> skuDTOs = spuDTO.getSkus();
            List<Sku> skuList = BeanHelper.copyWithCollection(skuDTOs, Sku.class);
            for (Sku sku : skuList) {
                sku.setSpuId(spu.getId()); //设置一对多的关系
                skuMapper.insertSelective(sku);
            }
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    @Autowired
    private AmqpTemplate amqpTemplate;

    public void updateSaleable(Long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
//        根据id 更新saleable
        spuMapper.updateByPrimaryKeySelective(spu);


        String routingKey = saleable?ITEM_UP_KEY:ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,routingKey,id);
        log.debug("已经成功的放入了消息："+id);
    }

    public SpuDetailDTO findSpuDetailBySpuId(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);
        if(spuDetail==null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail,SpuDetailDTO.class);
    }

    public List<SkuDTO> findSkuDTOListBySpuId(Long id) {
//       select * from tb_sku where spu_id=?
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> skuList = skuMapper.select(sku);
        if(CollectionUtils.isEmpty(skuList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skuList,SkuDTO.class);
    }

    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
//        spu的更新
//        SPUDetail的更新
//        sku的删除
//        sku的新增
        try {
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            spuMapper.updateByPrimaryKeySelective(spu);  //id  saleable  createTime  updateTime
//         tb_spu_detail spuDTO.getSpuDetail
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);

            spuDetailMapper.updateByPrimaryKeySelective(spuDetail);
//        tb_sku  spuDTO.getSkus
//            先删除
//            delete from tb_sku where spu_id=?
            Sku sku1 = new Sku();
            sku1.setSpuId(spu.getId());
            skuMapper.delete(sku1);
//            后新增
            List<SkuDTO> skuDTOs = spuDTO.getSkus();
            List<Sku> skuList = BeanHelper.copyWithCollection(skuDTOs, Sku.class);
            for (Sku sku : skuList) {
                sku.setSpuId(spu.getId()); //设置一对多的关系
                skuMapper.insertSelective(sku);
            }
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    public SpuDTO findSpuBySpuId(Long id) {
        Spu spu = spuMapper.selectByPrimaryKey(id);
        if(spu==null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spu,SpuDTO.class);

    }

    public List<SkuDTO> findSkusBySkuIds(List<Long> ids) {
        List<Sku> skuList = skuMapper.selectByIdList(ids);
        if(CollectionUtils.isEmpty(skuList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skuList,SkuDTO.class);
    }

    public void minusStock(Map<Long, Integer> skuNumMap) {
        try {
            for (Long skuId : skuNumMap.keySet()) {
                Sku sku = skuMapper.selectByPrimaryKey(skuId);
                Integer num = skuNumMap.get(skuId);
                sku.setStock(sku.getStock()-num);
                skuMapper.updateByPrimaryKeySelective(sku);
    //            update tb_sku set stock = 原库存-num where id=?
            }
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.STOCK_NOT_ENOUGH_ERROR);
        }
    }
}
